using System;
using System.Collections.Generic;
using Foreglance.MVP.Delegates;

namespace Foreglance.MVP.Models
{
    public abstract class Model<TEntity> : IModel<TEntity>
    {
        public event ObjectListEventHandler<TEntity> OnEntitiesSelectionChanged;
        public event ObjectListEventHandler<TEntity> OnEntitiesAdded;
        public event ObjectListEventHandler<TEntity> OnEntitiesEdited;
        public event ObjectListEventHandler<TEntity> OnEntitiesDeleted;

        protected Model()
        {
            Entities = new List<TEntity>();
            SelectedEntities = new List<TEntity>();
        }

        public void AddEntities()
        {
            var entities = SelectedEntities;
            //TODO
            FireEntitiesEvent(OnEntitiesAdded, entities);
        }

        public void EditEntities()
        {
            var entities = SelectedEntities;
            //TODO
            FireEntitiesEvent(OnEntitiesEdited, entities);
        }

        public void DeleteEntities()
        {
            var entities = new List<TEntity>(SelectedEntities);
            foreach (var entity in entities)
            {
                ValidateEntityExists(entity);
                Entities.Remove(entity);
            }
            SelectedEntities.Clear();
            FireEntitiesEvent(OnEntitiesDeleted, entities);
        }

        private void ValidateEntityExists(TEntity entity)
        {
            if(Entities.Contains(entity))
                return;
            throw new InvalidOperationException("Entity does not exist in the entity list");
        }

        public List<TEntity> Entities { get; private set; }

        public List<TEntity> SelectedEntities { get; set; }

        public TEntity Entity { get; set; }

        public void LoadEntities()
        {
            if(EntitiesLoaded)
                return;
            Entities = RequestEntityList();
            EntitiesLoaded = true;
        }

        private bool EntitiesLoaded { get; set; }

        protected abstract List<TEntity> RequestEntityList();

        private void FireEntitiesEvent(ObjectListEventHandler<TEntity> eventHandler, List<TEntity> entities)
        {
            if (eventHandler != null)
                eventHandler(this, entities);
        }

    }
}